package com.ibl.rover.lite.client.Sync.Parser;

import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.CircularRedirectException;
import com.ibl.rover.lite.client.Application.ApplicationContext;
import com.ibl.rover.lite.client.constants.RoverConstants;
import com.ibl.rover.lite.common.bean.OrderBean;
import com.ibl.rover.lite.common.bean.ProductOrderBean;
import com.ibl.rover.lite.common.db.Criteria;
import com.ibl.rover.lite.common.db.Criteria.Operators;
import com.ibl.rover.lite.common.db.DatabaseManager;
import com.mobile.sync.client.impl.RequestBean;
import com.mobile.sync.client.impl.RequestBean.RequestMethod;

public class SyncRequestBuilder {

	private ApplicationContext roverApp = null;
	private DatabaseManager manager;
	private String productCode, productUnitPrice, productQuantity;
	/* XML NODES and Attributes */
	private static final String SYNC_XML_ROOT = "<SyncXml>";
	private static final String SYNC_XML_ROOT_END = "</SyncXml>";
	private static final String SYNC_XML_HEAD = "<Head>";
	private static final String SYNC_XML_HEAD_END = "</Head>";
	private static final String SYNC_XML_AUTH = "<Auth>";
	private static final String SYNC_XML_AUTH_END = "</Auth>";
	private static final String SYNC_XML_BODY = "<Body>";
	private static final String SYNC_XML_BODY_END = "</Body>";
	private static final String SYNC_XML_SST = "<REQUEST>";
	private static final String SYNC_XML_SST_ENDS = "</REQUEST>";
	private static final String SYNC_XML_ATTR_START = "<attribute name=";
	private static final String SYNC_XML_VALUE = " value=";
	private static final String SYNC_XML_ATTR_ENDS = "/>";
	private static final String SYNC_XML_ITEM_ENDS = "</item>";
	private static final String SYNC_XML_ADD_STARTS = "<add>";
	private static final String SYNC_XML_ADD_ENDS = "</add>";
	private static final String SYNC_XML_LAST_UPDATED_ON = " lastUpdatedOn=";
	private static final String SYNC_XML_ENTITY_STARTS = "<entity name=";
	private static final String SYNC_XML_ENTITY_ENDS = "</entity>";
	private static final String SYNC_XML_END_OPEN_TAG = ">";

	private static final String SYNC_XML_HEADER = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";

	public SyncRequestBuilder(ApplicationContext context) {
		roverApp = context;
		manager = roverApp.getDatabaseManager();
	}

	public RequestBean buildLoginRequest(String userName) {
		String authUri = roverApp.getAppParams().getServerUrlPath();
		StringBuilder requestXml = new StringBuilder(SYNC_XML_HEADER
				+ SYNC_XML_ROOT);

		List<String> entityNameList = new ArrayList<String>();
		entityNameList.add(RoverConstants.CUSTOMERS);
		entityNameList.add(RoverConstants.APPSETUP);
		entityNameList.add(RoverConstants.PRODUCT);
		entityNameList.add(RoverConstants.PRODUCTS_CATEGORY);
		entityNameList.add(RoverConstants.ROUTE);

		buildHeader(requestXml, entityNameList, userName);

		requestXml.append(SYNC_XML_BODY);
		requestXml.append(SYNC_XML_BODY_END);
		requestXml.append(SYNC_XML_ROOT_END);

		RequestBean requestMessage = new RequestBean(authUri,
				RequestMethod.HttpPost);

		requestMessage.setDataChunk(requestXml.toString().getBytes());

		return requestMessage;
	}

	private void buildHeader(StringBuilder builder, List<String> entityList,
			String userName) {
		try {
			builder.append(SYNC_XML_HEAD);
			builder.append(SYNC_XML_AUTH);
			builder.append("<UserName>").append(userName).append("</UserName>");

			builder.append(SYNC_XML_AUTH_END);

			builder.append(SYNC_XML_SST);

			for (String singleEntity : entityList) {
				String syncEntityHeader = toEntitySyncHeader(singleEntity);
				builder.append(syncEntityHeader);
			}
			builder.append(SYNC_XML_SST_ENDS);
			builder.append(SYNC_XML_HEAD_END);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	private void buildHeaderSync(StringBuilder builder, String userName) {
		try {
			builder.append(SYNC_XML_HEAD);
			builder.append(SYNC_XML_AUTH);
			builder.append("<UserName>").append(userName).append("</UserName>");

			builder.append(SYNC_XML_AUTH_END);

			builder.append(SYNC_XML_SST);

			builder.append(SYNC_XML_SST_ENDS);
			builder.append(SYNC_XML_HEAD_END);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public String toEntitySyncHeader(String entityName) {
		StringBuilder builder = new StringBuilder();
		builder.append("<entity name=\"" + entityName + "\" />");
		return builder.toString();
	}

	public RequestBean buildSyncRequest(String userName) {
		try {
			StringBuilder requestXml = new StringBuilder(SYNC_XML_HEADER
					+ SYNC_XML_ROOT);
			buildHeaderSync(requestXml, userName);
			requestXml.append(SYNC_XML_BODY);
			buildOrderResponse(requestXml);
			requestXml.append(SYNC_XML_BODY_END);
			requestXml.append(SYNC_XML_ROOT_END);

			RequestBean requestBean = new RequestBean(roverApp.getAppParams()
					.getServerUrlPath(), RequestMethod.HttpPost);

			requestBean.setDataChunk(requestXml.toString().getBytes());
			return requestBean;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private void buildOrderResponse(StringBuilder builder) {
		try {

			List<OrderBean> orderList = manager.findAllBean(OrderBean.class);
			if (orderList.size() > 0) {
				builder.append(SYNC_XML_ENTITY_STARTS
						+ wrapInvertedComma("ORDER") + SYNC_XML_END_OPEN_TAG);
				for (OrderBean orderBean : orderList) {
					builder.append("<item>");
					Criteria<ProductOrderBean> criteria = manager
							.generateCriteria(ProductOrderBean.class);
					criteria.addRestriction("ORDERKEY", Operators.isEqual,
							orderBean.getOrderId());
					List<ProductOrderBean> list = criteria.execute();
					getCommaSeparatedProductCode(list);

					builder.append("<attribute name="
							+ wrapInvertedComma("ORDER_ID") + " value="
							+ wrapInvertedComma(orderBean.getOrderId()) + "/>");

					builder.append("<attribute name="
							+ wrapInvertedComma("CustomerCode") + " value="
							+ wrapInvertedComma(orderBean.getCustomerCode())
							+ "/>");

					builder.append("<attribute name="
							+ wrapInvertedComma("STATUS") + " value="
							+ wrapInvertedComma(orderBean.getStatus()) + "/>");

					builder.append("<attribute name="
							+ wrapInvertedComma("Amount") + " value="
							+ wrapInvertedComma(orderBean.getAmount()) + "/>");

					builder.append("<attribute name="
							+ wrapInvertedComma("SalesType") + " value="
							+ wrapInvertedComma(orderBean.getSalesType())
							+ "/>");

					builder.append("<attribute name="
							+ wrapInvertedComma("PRODUCT_ORDER_BEAN_CODE")
							+ " value=" + wrapInvertedComma(productCode) + "/>");

					builder.append("<attribute name="
							+ wrapInvertedComma("PRODUCT_ORDER_BEAN_QUANTITY")
							+ " value=" + wrapInvertedComma(productQuantity)
							+ "/>");

					builder.append("<attribute name="
							+ wrapInvertedComma("UNITPRICE") + " value="
							+ wrapInvertedComma(productUnitPrice) + "/>");

					builder.append(SYNC_XML_ITEM_ENDS);
				}
				builder.append(SYNC_XML_ENTITY_ENDS);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void getCommaSeparatedProductCode(
			List<ProductOrderBean> productOrderList) {
		productCode = "";
		productQuantity = "";
		productUnitPrice = "";
		StringBuilder idsList = new StringBuilder();
		StringBuilder quantityList = new StringBuilder();
		StringBuilder priceList = new StringBuilder();
		for (ProductOrderBean productOrderBean : productOrderList) {
			idsList.append(String.valueOf(productOrderBean.getProductCode())
					+ ",");
			quantityList.append(String.valueOf(productOrderBean.getQuantity())
					+ ",");
			priceList.append(String.valueOf(productOrderBean.getUnitPrice())
					+ ",");
		}
		if (0 < idsList.length()) {
			idsList.deleteCharAt(idsList.length() - 1);
			quantityList.deleteCharAt(quantityList.length() - 1);
			priceList.deleteCharAt(priceList.length() - 1);
		}
		productCode = idsList.toString();
		productQuantity = quantityList.toString();
		productUnitPrice = priceList.toString();
	}

	public String wrapInvertedComma(String str) {
		return str = "\"" + str + "\"";
	}

}
